package com.cloud.logger.zchain.zchainserver.service;

import com.cloud.logger.zchain.core.common.base.ResultMessage;
import com.cloud.logger.zchain.core.common.constant.ResultCodeConstant;
import com.cloud.logger.zchain.zchainserver.base.GlobalConstants;
import com.cloud.logger.zchain.zchainserver.entity.AngelaLoggerProject;
import com.cloud.logger.zchain.zchainserver.entity.AngelaLoggerProjectNode;
import com.cloud.logger.zchain.zchainserver.entity.AngelaLoggerProjectNodeDetail;
import com.cloud.logger.zchain.zchainserver.entity.ProjectUserRelation;
import com.cloud.logger.zchain.zchainserver.entity.propertyenum.SwitchEnum;
import com.cloud.logger.zchain.zchainserver.entity.propertyenum.UserStatusEnum;
import com.cloud.logger.zchain.zchainserver.mongo.AngelaProjectNodeDetailRepository;
import com.cloud.logger.zchain.zchainserver.mongo.AngelaProjectNodeRepository;
import com.cloud.logger.zchain.zchainserver.mongo.AngelaProjectRepository;
import com.cloud.logger.zchain.zchainserver.mongo.ProjectUserRelationRepository;
import com.cloud.logger.zchain.zchainserver.util.GlobalMap;
import com.cloud.logger.zchain.zchainserver.util.LoginUserThreadLocal;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mongodb.WriteResult;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import static org.springframework.data.mongodb.core.query.Update.update;

/**
 * 浙江卓锐科技股份有限公司
 *
 * @author zhengyt
 * @create 2017/12/11
 * @description
 */
@Service
public class AngelaLoggerProjectService {

    @Resource
    private ProjectUserRelationRepository projectUserRelationRepository;

    @Resource
    MongoTemplate mongoTemplate;

    @Resource
    private AngelaProjectNodeRepository nodeRepository;

    @Resource
    private AngelaProjectNodeDetailRepository nodeDetailRepository;

    @Resource
    private ProjectUserRelationRepository userRelationRepository;

    @Resource
    private AngelaProjectRepository angelaProjectRepository;

    @Resource
    private AngelaProjectNodeRepository angelaProjectNodeRepository;

    private static String TRUE_FLAG = "1";

    private Gson gson = new GsonBuilder().create();

    public ResultMessage saveProjectMultiUserRelation(ProjectUserRelation projectUserRelation){
        ResultMessage resultMessage = new ResultMessage();
        try {
            String[] userIdArray;
            if (StringUtils.isNotBlank(projectUserRelation.getUserId())) {
                userIdArray = projectUserRelation.getUserId().split(",");
            } else {
                resultMessage.setCode(ResultCodeConstant.SERVICE_ERROR_CODE);
                resultMessage.setMessage("用户id不能为空");
                return resultMessage;
            }
            List<ProjectUserRelation> relationList = projectUserRelationRepository.findByProjectId(projectUserRelation.getProjectId());
            ProjectUserRelation relation;
            if (relationList != null && relationList.size() > 0) {
                //删除该项目关联所有用户
                int i = projectUserRelationRepository.deleteByProjectId(projectUserRelation.getProjectId());
                if (i <= 0) {
                    resultMessage.setCode(ResultCodeConstant.SERVICE_ERROR_CODE);
                    resultMessage.setMessage("保存失败!");
                    return resultMessage;
                }
            }
            for (String userId : userIdArray) {
                relation = new ProjectUserRelation();
                relation.setUserId(userId);
                relation.setProjectId(projectUserRelation.getProjectId());
                projectUserRelationRepository.save(relation);
            }
        }catch (Exception e){
            System.out.println(e.getLocalizedMessage());
        }
        resultMessage.setCode(ResultCodeConstant.SERVICE_SUCCESS_CODE);
        return resultMessage;
    }

    public void startProject(String content) {
        AngelaLoggerProjectNode projectNode = gson.fromJson(content, AngelaLoggerProjectNode.class);

        checkProject(projectNode);
        saveProjectNode(projectNode, SwitchEnum.on);
    }

    private void checkProject(AngelaLoggerProjectNode node){
        //验证是否有客户信息
        AngelaLoggerProject company = mongoTemplate.findOne(
                query(where("code").is(node.getScenic()).and("parentNode").is("-1"))
                ,AngelaLoggerProject.class);
        if(company==null){
            company = new AngelaLoggerProject();
            WriteResult writeResult = mongoTemplate.upsert(query(where("code").is(node.getScenic()).and("parentNode").is("-1").and("name").is(node.getScenic())), update("createdDate", new Date()), AngelaLoggerProject.class);
            company.setId(writeResult.getUpsertedId().toString());
        }

        //验证是否有项目信息
        AngelaLoggerProject project = mongoTemplate.findOne(
                query(where("code").is(node.getCode()).and("parentNode").nin("-1"))
                ,AngelaLoggerProject.class);
        if(project==null){
            mongoTemplate.upsert(query(where("code").is(node.getCode()).and("name").is(node.getCode()).and("parentNode").is(company.getId())), update("createdDate", new Date()), AngelaLoggerProject.class);
        }

    }

    public void shutDownProject(String content){
        AngelaLoggerProjectNode projectNode = gson.fromJson(content, AngelaLoggerProjectNode.class);
        saveProjectNode(projectNode, SwitchEnum.off);

    }

    private void saveProjectNode(AngelaLoggerProjectNode projectNode, SwitchEnum status){
        //这里不能使用upsert，因为upsert在实体有枚举时候会直接保存一个枚举类
        AngelaLoggerProjectNode node = mongoTemplate.findOne(
                query(where("code").is(projectNode.getCode())
                        .and("ip").is(projectNode.getIp())
                        .and("port").is(projectNode.getPort()))
                ,AngelaLoggerProjectNode.class);
        if(node==null){
            node = projectNode;
        }

        node.setCreateTime(new Date());
        node.setStatus(status);
        nodeRepository.save(node);

        AngelaLoggerProjectNodeDetail nodeDetail = new AngelaLoggerProjectNodeDetail();
        nodeDetail.setCreateTime(new Date());
        nodeDetail.setCode(node.getCode());
        nodeDetail.setIp(node.getIp());
        nodeDetail.setPort(node.getPort());
        nodeDetail.setStatus(status);
        nodeDetailRepository.save(nodeDetail);
    }

    public ResultMessage findLoggerProject(){
        Sort sort = new Sort(Sort.Direction.DESC, "createdDate");
        AngelaLoggerProject filter = new AngelaLoggerProject();
        filter.setParentNode(-1+"");
        List<AngelaLoggerProject> projects = angelaProjectRepository.findByParentNode("-1", sort);

        //修改部分
        String token = LoginUserThreadLocal.getCurrentUser();
        String userType = (String) GlobalMap.getUserMap(token).get(GlobalConstants.USER_STATUS);
        List<ProjectUserRelation> userRelationList = null;
        ConcurrentHashMap map = null;
        if(UserStatusEnum.simple.getName().equals(userType)) {
            String userId = (String) GlobalMap.getUserMap(token).get(GlobalConstants.ID);
            userRelationList = userRelationRepository.findByUserId(userId);
            map = new ConcurrentHashMap();
            for(ProjectUserRelation userRelation : userRelationList){
                map.put(userRelation.getProjectId(),TRUE_FLAG);
            }
        }

        Iterator it = projects.iterator();
        while (it.hasNext()){
            AngelaLoggerProject project = (AngelaLoggerProject)it.next();
            filter.setParentNode(project.getId());
            List<AngelaLoggerProject> children = angelaProjectRepository.findByParentNode(project.getId(), sort);

            //验证权限部分
            if(UserStatusEnum.simple.getName().equals(userType) && children !=null && children.size() != 0){

                Iterator childerIterator = children.iterator();
                while (childerIterator.hasNext()){
                    AngelaLoggerProject childrenProject = (AngelaLoggerProject)childerIterator.next();
                    if(!TRUE_FLAG.equals(map.get(childrenProject.getId()))){
                        childerIterator.remove();
                    }
                }

            }

            project.setChildren(children);
        }
        ResultMessage resultMessage = new ResultMessage();
        resultMessage.setCode(ResultCodeConstant.SERVICE_SUCCESS_CODE);
        resultMessage.setContent(projects);
        return resultMessage;
    }


    public ResultMessage updateProjectNode(AngelaLoggerProjectNode angelaLoggerProjectNode){
        ResultMessage resultMessage = new ResultMessage();
        try {
            angelaProjectNodeRepository.save(angelaLoggerProjectNode);
            if (angelaLoggerProjectNode.getId() !=null){
                resultMessage.setCode(ResultCodeConstant.SERVICE_SUCCESS_CODE);
                resultMessage.setId(angelaLoggerProjectNode.getId()+"");
            }else{
                resultMessage.setCode(ResultCodeConstant.SERVICE_ERROR_CODE);
            }
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
            resultMessage.setCode(ResultCodeConstant.SERVICE_ERROR_CODE);
        }
        return resultMessage;
    }

}